from app import app, babel, db
from models import *
from flask import render_template, request, redirect, url_for, flash
from forms import EmployeeForm
from config import LANGUAGES
from flask.ext.babel import gettext
from config import DATEFORMAT
from datetime import datetime
from flask import jsonify, make_response, abort, send_file, send_from_directory
from utils import debug

@babel.localeselector
def get_locale():
	return request.accept_languages.best_match(LANGUAGES.keys())


@app.route('/pygem')
def pygem():
	app.logger.info('pygem starting...')
	return render_template('pygem.html')

@app.route('/test/employeestest')
def employeestest():
	app.logger.info('employees test requested')
	app.logger.info(app.static_folder)
	return app.send_static_file('employeestest.html')

@app.route('/pygem/testpage')
def testpage():
	app.logger.info('testpage...')
	return render_template('testpage.html')

@app.route('/pygem/api/v1.0/notifications')
def notifications():
	return 'under construction'

@app.errorhandler(404)
def not_found(error):
	app.logger.info('entity not found')
	return make_response(jsonify( { 'error': 'Not found.' } ), 404)

# -----------------RESTful API ---------------------
# Gets the whole departments tree
# --------------------Departments-----------------------
@debug
@app.route('/pygem/api/v1.0/departments', methods=['GET'])
def get_departments():
	app.logger.info('getting departments')
	departments = {department.departmentid: department.exportasJSON() for department in Department.query.all()}
	return jsonify({'departments': departments})

# Gets depeartment id
@debug
@app.route('/pygem/api/v1.0/departments/<int:dep_id>', methods=['GET'])
def get_department(dep_id):
	app.logger.info('getting department id=%s' % dep_id)
	department = Department.query.get(dep_id)
	if department:
		return jsonify({'department': department.exportasJSON()})
	else:
		abort(404)

@app.route('/pygem/api/v1.0/departments/<int:dep_id>', methods=['DELETE'])
def delete_department(dep_id):
	app.logger.info('deleting department id=%s' % dep_id)
	department = Department.query.get(dep_id)
	if department:
		db.session.delete(d) # This will not delete sciencedomains nor courses associated with it.
		db.session.commit()
		app.logger.info('department deleted')
		return jsonify({'result': True})
	else:
		abort(404)

@debug
@app.route('/pygem/api/v1.0/departments/<int:dep_id>', methods=['PUT'])
def update_department(dep_id):
	app.logger.info('updating department %s' % dep_id)
	department = Department.query.get(dep_id)
	if department:
		if request.json and 'departmenttitle' in request.json:
			department.departmenttitle = request.json['departmenttitle']
			db.session.add(department)
			db.session.commit()
			app.logger.info('department updated %s' % repr(department))
			return jsonify({'result': True})
		else:
			return abort(400) # check about this
	else:
		abort(404)

@debug
@app.route('/pygem/api/v1.0/departments', methods=['POST'])
def create_department():
	if request.json and 'departmenttitle' in request.json:
		department = Department(departmenttitle=request.json['departmenttitle'])
		app.logger.info('creating new department.' + str(department))
		db.session.add(department)
		db.session.commit()
		app.logger.info('department created, returning response back ' + str(department.exportasJSON()))
		return jsonify({'department': department.exportasJSON()}), 201
	else:
		app.logger.error('invalid data sent. ' + str(request.json))
		abort(400)


#------------------ScienceDomain-------------------------
@debug
@app.route('/pygem/api/v1.0/sciencedomains', methods=['GET'])
def get_sciencedomains():
	app.logger.info('getting sciencedomains...')
	sciencedomains = {sciencedomain.sciencedomainid : sciencedomain.exportasJSON() for sciencedomain in ScienceDomain.query.all()}
	return jsonify({'sciencedomains' : sciencedomains})

@debug
@app.route('/pygem/api/v1.0/sciencedomains/<int:sd_id>', methods=['GET'])
def get_sciencedomain(sd_id):
	app.logger.info('getting sciencedomain id=%s' %sd_id)
	sciencedomain = ScienceDomain.query.get(sd_id)
	if sciencedomain:
		return jsonify({'sciencedomain': sciencedomain.exportasJSON()})
	else:
		abort(404)

@debug
@app.route('/pygem/api/v1.0/sciencedomains/<int:sd_id>', methods=['PUT'])
def update_sciencedomain(sd_id):
	app.logger.info('updating sciencedomain %s' % sd_id)
	sciencedomain = ScienceDomain.query.get(sd_id)
	if sciencedomain:
		if request.json:
			department = Department.query.get(request.json['departmentid']) if 'departmentid' in request.json else None
			if department and sciencedomain.parentdepartment != department:
				app.logger.info('setting parent department for %s' % sciencedomain.sciencedomaintitle)
				sciencedomain.parentdepartment = department
			if 'sciencedomaintitle' in request.json:
				sciencedomain.sciencedomaintitle = request.json['sciencedomaintitle']
			db.session.add(sciencedomain)
			db.session.commit()
			app.logger.info('sciencedomain updated ' + repr(sciencedomain))
			return jsonify({'result': True})
		else:
			abort(400)
	else:
		abort(404)

@debug
@app.route('/pygem/api/v1.0/sciencedomains/<int:sd_id>', methods=['DELETE'])
def delete_sciencedomain(sd_id):
	app.logger.info('deleting sciencedomain id=%s' % sd_id)
	sciencedomain = ScienceDomain.query.get(sd_id)
	if sciencedomain:
		app.logger.info('deleting sciencedomain %s' % repr(sciencedomain))
		db.session.delete(sciencedomain)
		db.session.commit()
		return jsonify({'result': True})
	else:
		return abort(404)

@debug
@app.route('/pygem/api/v1.0/sciencedomains', methods=['POST'])
def create_sciencedomain():
	app.logger.info('creating sciencedomain')
	if request.json and 'sciencedomaintitle' in request.json:
		sciencedomain = ScienceDomain(sciencedomaintitle = request.json['sciencedomaintitle'])
		if 'departmentid' in request.json:
			department = Department.query.get(request.json['departmentid'])
			if department:
				sciencedomain.parentdepartment = department
		db.session.add(sciencedomain)
		db.session.commit()
		app.logger.info('sciencedomain created successfully %s' % repr(sciencedomain))
		return jsonify({'sciencedomain': sciencedomain.exportasJSON()}), 201
	else:
		return abort(400)


# ------------------- Courses -------------------------
@debug
@app.route('/pygem/api/v1.0/courses', methods=['GET'])
def get_courses():
	app.logger.info('getting courses')
	courses = {course.courseid: course.exportasJSON() for course in Course.query.all()}
	return jsonify({'courses': courses})

@debug
@app.route('/pygem/api/v1.0/courses/<int:c_id>', methods=['GET'])
def get_course(c_id):
	app.logger.info('getting course %s' % c_id)
	course = Course.query.get(c_id)
	if course:
		return jsonify({'course' : course.exportasJSON()})
	else:
		abort(404)

@debug
@app.route('/pygem/api/v1.0/courses/<int:c_id>', methods=['DELETE'])
def delete_course(c_id):
	app.logger.info('deleting course %s' % c_id)
	course = Course.query.get(c_id)
	if course:
		db.session.delete(c)
		db.session.commit()
		return jsonify({'result': True})
	else:
		abort(404)


@debug
@app.route('/pygem/api/v1.0/courses/<int:c_id>', methods=['PUT'])
def update_course(c_id):
	app.logger.info('updating course')
	course = Course.query.get(c_id)
	if course:
		coursetitle = request.json['coursetitle']
		if course.coursetitle != coursetitle:
			course.coursetitle = coursetitle
		sciencedomain = ScienceDomain.query.get(request.json['sciencedomainid'])
		if sciencedomain and course.parentsciencedomain != sciencedomain:
			course.parentsciencedomain = sciencedomain
		db.session.add(course)
		db.session.commit()
		app.logger.info('course updated %s' % repr(course))
		return jsonify({'result': True})
	else:
		abort(404)

@debug
@app.route('/pygem/api/v1.0/courses', methods=['POST'])
def create_course():
	app.logger.info('creating course')
	if request.json and 'coursetitle' in request.json:
		course = Course(coursetitle = request.json['coursetitle'])
		if 'sciencedomainid' in request.json:
			sciencedomain = ScienceDomain.query.get(request.json['sciencedomainid'])
			if sciencedomain:
				course.parentsciencedomain = sciencedomain
		db.session.add(course)
		db.session.commit()
		app.logger.info('new course created %s' % repr(course))
		return jsonify({'course': course.exportasJSON()}), 201
	else:
		abort(400)

# ---------------------- Employees ---------------------------------
@debug
@app.route('/pygem/api/v1.0/employees', methods=['GET'])
def get_employees():
	app.logger.info('getting employees')
	employees = {employee.employeeid: employee.exportasJSON() for employee in Employee.query.all()}
	return jsonify({'employees': employees})

@debug
@app.route('/pygem/api/v1.0/employees/<int:emp_id>', methods=['GET'])
def get_employee(emp_id):
	app.logger.info('getting employee %s' % emp_id)
	employee = Employee.query.get(emp_id)
	if employee:
		return jsonify({'employee': employee.exportasJSON()})
	else:
		abort(404)

@debug
@app.route('/pygem/api/v1.0/employees/<int:emp_id>', methods=['PUT'])
def update_employee(emp_id):
	app.logger.info('updating employee %s' % emp_id)
	employee = Employee.query.get(emp_id)
	if employee:
		if request.form:
			for fieldname, fieldvalue in request.form.items():
				if fieldname == 'employeeid':
					continue
				if 'date' in fieldname:
					app.logger.info('found date %s=%s converting...' % (fieldname, fieldvalue))
					fieldvalue = datetime.strptime(fieldvalue, DATEFORMAT)
					app.logger.info('converted data %s', fieldvalue)
				if fieldvalue != getattr(employee, fieldname, fieldvalue):
					# This is to way around the AttributeError. If employee doesn't have attribute from the form, return field.data
					# For instance, this is useful for csfr_token, which form does have, and employee doesn't
					# TODO: add makevalidname
					app.logger.info('changed data %s=%s and was%s: ' % (fieldname, fieldvalue, getattr(employee, fieldname)))
					setattr(employee, fieldname, fieldvalue)
			db.session.add(employee)
			db.session.commit()
			app.logger.info('employee updated %s' % employee.exportasJSON())
			return jsonify({'result': True})
		else:
			app.logger.info('requets json' + str(request.json))
			app.logger.info('requets args' + str(request.args))
			app.logger.info('requets form' + str(request.form))
			abort(400)
	else:
		abort(404)

@debug
@app.route('/pygem/api/v1.0/employees/<int:emp_id>', methods=['DELETE'])
def delete_employee(emp_id):
	app.logger.info('deleting employee %s' % emp_id)
	employee = Employee.query.get(emp_id)
	if employee:
		db.session.delete(employee)
		db.session.commit()
		return jsonify({'result': True})
	else:
		abort(404)

@debug
@app.route('/pygem/api/v1.0/employees', methods=['POST'])
def create_employee():
	app.logger.info('creating new employee')
	if request.json:
		employee = Employee()
		for fieldname, fieldvalue in request.json:
			employee.setattr(fieldname, fieldvalue)
		db.session.add(employee)
		db.session.commit()
		app.logger.info('new employee created successfully %s' % repr(employee))
		return jsonify({'employee': employee.exportasJSON()})
	else:
		abort(400)


@app.route('/pygem/api/v1.0/employeejobtype', methods=['POST'])
def create_employeejobtype():
	pass

# Currently, a user only can edit dates. User can not modify actual employeejobtype
# The only way to alter it is to remove it and to create new one.
@app.route('/pygem/api/v1.0/employeejobtype', methods=['PUT'])
def update_employeejobtype():
	app.logger.info('update_employeejobtype')
	if request.form:
		app.logger.info('request.form is not none' + request.form)
		employeeJobTypeID = request.form['employeejobtypeid']
		if 'employeejobtypeid' in employeeJobTypeID:
			employeeJobTypeID = employeeJobTypeID.split('_')[1]
		employeeJobType = EmployeeJobType.query.get(employeeJobTypeID)
		if employeeJobType:
			app.logger.info('found employee job type' + employeeJobType)
			# data is valid...
			employeeJobTypeStartDate = datetime.strptime(requets.form['employeejobtypestartdate'], DATEFORMAT)
			employeeJobTypeEndDate = datetime.strptime(request.form['employeejobtypeenddate'], DATEFORMAT)
			employeeJobTypeActive = bool(request.form['employeejobtypeactive'])
			
			employeeJobType.employeejobtypestartdate = employeeJobTypeStartDate
			employeeJobType.emploeejobtypeenddate = employeeJobTypeEndDate
			employeeJobType.employeeJobTypeActive = employeeJobTypeActive
			
			app.logger.info('saving the employeejobtype')
			db.session.add(employeejobtype)
			db.session.commit()
			app.logger.info('employeejobtype saved!')
			return jsonify({'result': True})			
		else:
			app.logger.error('employeeJobType not found for id=' + employeeJobTypeID)
			abort(404)
	else:
		app.logger.error('request.form is None')
		abort(400)	

@app.route('/pygem/api/v1.0/employeejobtype', methods=['GET'])
def get_employeejobtype():
	pass

@app.route('/pygem/api/v1.0/employeejobtype', methods=['DELETE'])
def delete_employeejobtype():
	pass
# -------------------- Jobs ----------------------------
@app.route('/pygem/api/v1.0/jobs', methods=['GET'])
def get_jobs():
	app.logger.info('getting jobs')
	jobs = {job.jobid : job.exportasJSON() for job in Job.query.all()}
	return jsonify({'jobs': jobs})

@app.route('/pygem/api/v1.0/jobs/<int:job_id>', methods=['GET'])
def get_job(job_id):
	app.logger.info('getting job id=%s' % job_id)
	job = Job.query.get(job_id)
	if job:
		return jsonify({'job': job.exportasJSON()})
	else:
		abort(404)

@app.route('/pygem/api/v1.0/jobs/<int:job_id>', methods=['PUT'])
def update_job(job_id):
	app.logger.info('updating job, id=%s' % job_id)
	job = Job.query.get(job_id)
	if job:
		if request.json and 'jobtitle' in request.json:
			job.jobtitle = request.json['jobtitle']
			db.session.add(job)
			db.session.commit()
			app.logger.info('job updated %s' % repr(job))
			return jsonify({'result': True})
		else:
			abort(400)
	else:
		abort(404)

@app.route('/pygem/api/v1.0/jobs/<int:job_id>', methods=['DELETE'])
def delete_job(job_id):
	app.logger.info('deleting job id = %s' % job_id)
	job = Job.query.get(job_id)
	if job:
		db.session.delete(job)
		db.session.commit()
		app.logger.info('job deleted successfully')
		return jsonify({'result': True})
	else:
		abort(404)

@app.route('/pygem/api/v1.0/jobs', methods=['POST'])
def create_job():
	app.logger.info('creating new job')
	if request.json and 'jobtitle' in request.json:
		job = Job(jobtitle=request.json['jobtitle'])
		db.session.add(job)
		db.session.commit()
		app.logger.info('job created successfully %s' % repr(job))
		return jsonify({'job': job.exportasJSON()})
	else:
		abort(400)
# -------------------- JobType --------------------------
@app.route('/pygem/api/v1.0/jobtypes', methods=['GET'])
def get_jobtypes():
	app.logger.info('getting jobtypes')
	jobtypes = {jobtype.jobtypeid: jobtype.exportasJSON() for jobtype in JobType.query.all()}
	return jsonify({'jobtypes': jobtypes})

@app.route('/pygem/api/v1.0/jobtypes/<int:job_type_id>', methods=['GET'])
def get_jobtype(job_type_id):
	app.logger.info('getting jobtype id=%s' % job_type_id)
	jobtype = JobType.query.get(job_type_id)
	if jobtype:
		return jsonify({'jobtype': jobtype.exportasJSON()})
	else:
		abort(404)

@app.route('/pygem/api/v1.0/jobtypes/<int:job_type_id>', methods=['PUT'])
def update_jobtype(job_type_id):
	app.logger.info('updating jobtype id=%s' % job_type_id)
	jobtype = JobType.query.get(job_type_id)
	if jobtype:
		if request.json:
			if 'jobtypetitle' in request.json:
				jobtype.jobtypetitle = request.json['jobtypetitle']
			if 'jobid' in request.json:
				job = Job.query.get(request.json['jobid'])
				if job and jobtype.parentjob != job:
					jobtype.parentjob = job
			db.session.update(jobtype)
			db.session.commit()
			app.logger.info('jobtype updated %s' % repr(jobtype))
			return jsonify({'result': True})
		else:
			abort(400)
	else:
		abort(404)

@app.route('/pygem/api/v1.0/jobtypes', methods=['POST'])
def create_jobtype():
	app.logger.info('creating new jobtype')
	if request.json and 'jobtypetitle' in request.json:
		jobtype = JobType(jobtypetitle=request.json['jobtypetile'])
		if 'jobid' in request.json:
			job = Job.query.get(request.json['jobid'])
			if job and jobtype.parentjob != job:
				jobtype.parentjob = job
		db.session.add(jobtype)
		db.session.commit()
		app.logger.info('jobtype created %s' % repr(jobtype))
		return jsonify({'result':True})
	else:
		abort(400)

@app.route('/pygem/api/v1.0/jobtypes/<int:job_type_id>', methods=['DELETE'])
def delete_jobtype(job_type_id):
	app.logger.info('deleting jobtype %s' % job_type_id)
	jobtype = JobType.query.get(job_type_id)
	if jobtype:
		db.session.delete(jobtype)
		db.session.commit()
		return jsonify({'result':True})
	else:
		abort(404)

# -------------------- Education ------------------------------
@app.route('/pygem/api/v1.0/educationlevels', methods=['GET'])
def get_educationlevels():
	app.logger.info('getting educationlevels')
	educationlevels = {educationlevel.educationlevelid: educationlevel.exportasJSON() for educationlevel in EducationLevel.query.all()}
	return jsonify({'educationlevels': educationlevels})

@app.route('/pygem/api/v1.0/educationlevels/<int:educationlevel_id>', methods=['GET'])
def get_educationlevel(educationlevel_id):
	app.logger.info('getting educationlevel id=%s' % educationlevel_id)
	educationlevel = EducationLevel.query.get(educationlevel_id)
	if educationlevel:
		return jsonify({'eudcationlevel': educationlevel.exportasJSON()})
	else:
		abort(404)

@app.route('/pygem/api/v1.0/educationlevels/<int:educationlevel_id>', methods=['PUT'])
def update_educationlevel(educationlevel_id):
	app.logger.info('updating educationlevel id=%s' % educationlevel_id)
	educationlevel = EducationLevel.query.get(educationlevel_id)
	if educationlevel:
		if 'educationleveltitle' in request.json:
			educationlevel.educationleveltitle = request.json['educationleveltitle']
		if 'educationleveltag' in request.json:
			educationlevel.educationleveltag = request.json['educationleveltag']
		db.session.add(educationlevel)
		db.session.commit()
		app.logger.info('educationlevel updated %s' % repr(educationlevel))
		return jsonify({'result': True})
	else:
		abort(404)

@app.route('/pygem/api/v1.0/educatioeducationlevelsns/<int:educationlevel_id>', methods=['DELETE'])
def delete_educationlevel(educationlevel_id):
	app.logger.info('deleting educationlevel id=%s' % educationlevel_id)
	educationlevel = EducationLevel.query.get(educationlevel_id)
	if educationlevel:
		db.session.delete(educationlevel)
		db.session.commit()
		app.logger.info('educationlevel deleted')
		return jsonify({'result':True})
	else:
		abort(404)

@app.route('/pygem/api/v1.0/educationlevels', methods=['POST'])
def create_educationlevel():
	app.logger.info('creating educationlevel')
	if request.json and 'educationleveltitle' in request.json:
		educationlevel = EducationLevel(educationleveltitle='educationleveltitle')
		if 'educationleveltag' in request.json:
			educationlevel.educationleveltag = request.json['educationleveltag']
		db.session.add(educationlevel)
		db.session.commit()
		app.logger.info('educationlevel created %s' % repr(educationlevel))
		return jsonify({'result':True})
	else:
		abort(400)

# ----------------Current----------------------
@app.route('/pygem/courses', methods=['GET'])
def courses():
	app.logger.info('getting courses')
	departments = {department.departmentid: department.exportasJSON() for department in Department.query.all()}
	# departments = [department.exportasJSON() for department in Department.query.all()]
	return render_template('coursesview.html', departments=departments)


@app.route('/')
@app.route('/index')
def index():
	app.logger.info('fetching employees...')
	employees = Employee.query.all()
	return render_template('base.html', employees=employees, form=EmployeeForm())

@app.route('/employeeslist')
def employeeslist():
	app.logger.info('fetching employees...')
	employees = Employee.query.all()
	return render_template('employeeslist.html', employees=employees)

@app.route('/employee/<id>', methods=['GET', 'POST'])
def employee(id):
	id = request.form['employeeid'] if request.method == 'POST' else id
	app.logger.info('employee(%s) method=%s' % (id, request.method))
	employee = Employee.query.get(id)
	app.logger.info('starting with processing the request %s', request.method == 'POST')
	if request.method == 'POST':
		flash('Employee data posted ')
		app.logger.info('employee data posted and validated')
		dirty = False
		for fieldname, fielddata in request.form.items():
			if fieldname == 'employeeid':
				continue
			if 'date' in fieldname:
				app.logger.info('found date %s=%s converting...' % (fieldname, fielddata))
				fielddata = datetime.strptime(fielddata, DATEFORMAT)
				app.logger.info('converted data %s', fielddata)
			if fielddata != getattr(employee, fieldname, fielddata):
				# This is to way around the AttributeError. If employee doesn't have attribute from the form, return field.data
				# For instance, this is useful for csfr_token, which form does have, and employee doesn't
				# TODO: add makevalidname
				app.logger.info('changed data %s=%s and was%s: ' % (fieldname, fielddata, getattr(employee, fieldname)))
				setattr(employee, fieldname, fielddata)
				dirty = True
		if dirty:
			app.logger.info('saving employee...')
			db.session.add(employee)
			db.session.commit()

	return employee.exportasJSON()


@app.route('/courses', methods=['GET'])
def coursestreeview():
	return ''

